package com.app.brilliant.sys.service.impl;

import com.app.brilliant.common.exception.BusinessException;
import com.app.brilliant.common.service.impl.BaseServiceImpl;
import com.app.brilliant.common.vo.PageContainer;
import com.app.brilliant.game.response.DevUserListInfo;
import com.app.brilliant.shiro.cache.LoginRedisService;
import com.app.brilliant.shiro.convert.DevUserConvert;
import com.app.brilliant.shiro.param.RegisterParam;
import com.app.brilliant.shiro.util.SaltUtil;
import com.app.brilliant.sign.constant.Constants;
import com.app.brilliant.sms.AliyunSmsService;
import com.app.brilliant.sys.bean.DevUser;
import com.app.brilliant.sys.params.DevUserListPageParam;
import com.app.brilliant.sys.service.DevUserService;
import com.app.brilliant.sys.mapper.DevUserMapper;
import com.app.brilliant.util.IpUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

/**
 * @author GF
 * @description 针对表【dev_user(系统用户)】的数据库操作Service实现
 * @createDate 2025-07-25 11:53:21
 */
@Service
public class DevUserServiceImpl extends BaseServiceImpl<DevUserMapper, DevUser>
        implements DevUserService {

    @Autowired
    private LoginRedisService loginRedisService;

    @Autowired
    private AliyunSmsService smsService;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean register(RegisterParam param) throws Exception {
        DevUser devUser = DevUserConvert.INSTANCE.registerParamToDevUser(param);
        // 校验用户名是否存在
        boolean isExists = isExistsByUsername(param.getUsername());
        if (isExists) {
            throw new BusinessException("用户名已存在");
        }
        // 生成盐值
        String salt = SaltUtil.generateSalt();
        devUser.setSalt(salt);
        devUser.setIp(IpUtil.getRequestIp());
        devUser.setState(Constants.NomalIntValue.STATE_OK);
        devUser.setEmail(param.getEmail());
        devUser.setCreateTime(new Date(System.currentTimeMillis()));
        devUser.setNickName(param.getUsername());
        // 保存用户
        return super.save(devUser);
    }

    @Override
    public PageContainer<DevUserListInfo> devUserList(DevUserListPageParam devUserListPageParam) {
        Page page = setPageParam(devUserListPageParam);
        return PageContainer.of(baseMapper.devUserList(page, devUserListPageParam));
    }

    @Override
    public boolean changeDevUserState(Integer uid, Integer state) {
        DevUser wxUser = getById(uid);
        wxUser.setState(state);
        if (state.intValue() != Constants.NomalIntValue.STATE_OK) {
            loginRedisService.deleteDevUserAllCache(wxUser.getId()+"");
        }
        return updateById(wxUser);
    }

    @Override
    public DevUser getByUsername(String username) {
        QueryWrapper<DevUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return getOne(queryWrapper);
    }

    @Override
    public DevUser getByEmail(String email) {
        QueryWrapper<DevUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("email", email);
        return getOne(queryWrapper);
    }

    @Override
    public DevUser getByOpenId(String openId) {
        QueryWrapper<DevUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("open_id", openId);
        return getOne(queryWrapper);
    }

    @Override
    public DevUser getDevUserBySalt(String salt) {
        QueryWrapper<DevUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("salt", salt);
        return getOne(queryWrapper);
    }

    private boolean isExistsByUsername(String username) {
        QueryWrapper<DevUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username", username);
        return retBool(super.count(queryWrapper));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean bindPhone(Integer userId, String phone, String code) {
        // 1. 验证验证码
        if (!smsService.verifyCode(phone, code, "BIND_PHONE")) {
            throw new BusinessException("验证码错误或已过期");
        }

        // 2. 更新用户手机号
        DevUser user = getById(userId);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        user.setPhone(phone);
        return updateById(user);
    }

    @Override
    public boolean sendBindPhoneCode(String phone) {
        // 1. 生成4位验证码
        String code = String.valueOf((int) (Math.random() * 9000) + 1000);

        // 2. 发送短信
        return smsService.sendSms(phone, code, "BIND_PHONE");
    }
}
